package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"path/filepath"

	fileAnalyser "gitcode.com/hammerklavier/Pathology_Picture_Book/Developer_Tools/reference_file_checker/src/file_analyser"
)

func main() {
	initArgs()

	err := os.Chdir(myArgs.WorkingDir)
	if err != nil {
		fmt.Println("Error when setting working directory:", err)
		os.Exit(1)
	}

	if myArgs.NoGUI {
		noGUI()
	} else {
		os.Exit(1)
	}

}

type Args struct {
	// TODO: add args
	NoGUI                       bool
	WorkingDir                  string
	AllowJsonMissingness        bool
	AllowDescriptionMissingness bool
}

var myArgs = Args{}

func initArgs() {
	flag.BoolVar(&myArgs.NoGUI, "nogui", true, "Use this flag to disable GUI.")
	flag.StringVar(&myArgs.WorkingDir, "workingdir", ".", "Use this flag to specify the working directory.")
	flag.BoolVar(&myArgs.AllowJsonMissingness, "allow-json-missingness", false, "Use this flag to allow json missingness.")
	flag.BoolVar(&myArgs.AllowDescriptionMissingness, "allow-description-missingness", false, "Use this flag to allow description missingness.")
	flag.Parse()

	// check if working dir exists
	_, err := os.Stat(myArgs.WorkingDir)
	if os.IsNotExist(err) {
		// Report error and exit
		flag.PrintDefaults()
		fmt.Println("Error: Working directory does not exist.")
		os.Exit(1)
	}
}

// Currently only noGUI is supported.
func noGUI() {

	wd, _ := os.Getwd()
	log.Println("Current working directory:", wd)

	// Get json data
	json_slice, err := fileAnalyser.GetJsonData("./reference.json")
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(1)
	}

	// Get picture paths
	picture_paths, err := fileAnalyser.GetPicturePaths(wd)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(1)
	}

	// check if pictures paths are all correctly recorded in json
	// 1. get all picture paths recorded in json
	var json_picture_paths []string
	for _, catagory := range json_slice {
		for _, json_picture_map := range catagory["pictures"].([]interface{}) {
			json_picture_abs_path, err := filepath.Abs(json_picture_map.(map[string]interface{})["file_path"].(string))
			// change to standard relative path
			if err != nil {
				panic(err)
			}
			json_picture_rel_path, err := filepath.Rel(wd, json_picture_abs_path)
			if err != nil {
				panic(err)
			}
			json_picture_paths = append(json_picture_paths, json_picture_rel_path)
		}
	}
	// 2. compare
	// 2.1 check if json contains non-existing pictures.
	json_picture_path_check := make([]bool, len(json_picture_paths))
	picture_path_recorded_check := make([]bool, len(picture_paths))
	{
		for json_picture_path_index, json_picture_path := range json_picture_paths {
			var matched bool
			for _, picture_path := range picture_paths {
				if json_picture_path == picture_path {
					matched = true
					break
				}
			}
			if matched {
				json_picture_path_check[json_picture_path_index] = true
			}
		}
	}
	// 2.2 check if there is missing record in json
	log.Printf("Allow Json Missingness is %t\n", myArgs.AllowJsonMissingness)
	if !myArgs.AllowJsonMissingness {
		for picture_path_index, picture_path := range picture_paths {
			var matched bool
			for _, json_picture_path := range json_picture_paths {
				if picture_path == json_picture_path {
					matched = true
					break
				}
			}
			if matched {
				picture_path_recorded_check[picture_path_index] = true
			}
		}
	} else {
		for i := 0; i < len(picture_path_recorded_check); i++ {
			picture_path_recorded_check[i] = true
		}
	}
	fmt.Println()
	fmt.Println(json_picture_path_check, "\n", picture_path_recorded_check)

	// check if there are pictures lacking descriptions.
	if !myArgs.AllowDescriptionMissingness {
		for _, catagory := range json_slice {
			for _, json_picture_map := range catagory["pictures"].([]interface{}) {
				if json_picture_map.(map[string]interface{})["description"] == nil {
					fmt.Println("Warning: Picture", json_picture_map.(map[string]interface{})["file_path"], "has no description.")
				}
			}
		}
	}
	// report result
	fmt.Println("==== Missingness Check Result ====")
	fmt.Println("-- Pictures Missing in Json: --")
	for json_picture_path_index, json_picture_path_check_result := range json_picture_path_check {
		if !json_picture_path_check_result {
			fmt.Println(json_picture_paths[json_picture_path_index])
		}
	}
	fmt.Println("-- Pictures Missing in Picture Folder: --")
	for picture_path_index, picture_path_recorded_check_result := range picture_path_recorded_check {
		if !picture_path_recorded_check_result {
			fmt.Println(picture_paths[picture_path_index])
		}
	}

	os.Exit(0)
}
